﻿using System;


namespace BizElements.BusinessLayer
{
    /// <summary>
    /// Remotes method invocation to a specified process.
    /// </summary>
    public interface IMethodRemoter
    {
        #region Methods.

        /// <summary>Marshals object to process defined by the remoter, executes the method and returns the changed object and method's return value to source domain.</summary>
        /// <param name="obj">Object which is to be marshalled to the defined process and supports the execution 
        /// of the specified method. May be changed in remote domain. Must be marked with 
        /// <see cref="System.SerializableAttribute"/> atribute.</param>
        /// <param name="methodName">Method which is to be executed in the remote domain.</param>
        /// <param name="methodParameters">Method parameters. May not be changed in remote domain. Passed by value.
        /// All parameters must be marked with <see cref="System.SerializableAttribute"/> atribute.</param>
        /// <returns>Method's return value. Must be marked with <see cref="System.SerializableAttribute"/> atribute.</returns>
        object InvokeMethod(object obj, string methodName, params object[] methodParameters);

        /// <summary>Marshals method arguments to process defined by the remoter, executes the method and returns the method's return value to source domain.</summary>
        /// <param name="type">Type which contains the specified static method.</param>
        /// <param name="methodName">Method to be executed.</param>
        /// <param name="methodParameters">Method parameters. May not be changed in remote domain. Passed by value.
        /// All parameters must be marked with <see cref="System.SerializableAttribute"/> atribute.</param>
        /// <returns>Method's return value. Must be marked with <see cref="System.SerializableAttribute"/> atribute.</returns>
        object InvokeStaticMethod(Type type, string methodName, params object[] methodParameters);

        /// <summary>Marshals object to process defined by the remoter, executes the generic method and returns the changed object and method's return value to source domain.</summary>
        /// <param name="obj">Object which is to be marshalled to the defined process and supports the execution 
        /// of the specified method. May be changed in remote domain. Must be marked with 
        /// <see cref="System.SerializableAttribute"/> atribute.</param>
        /// <param name="methodName">Method which is to be executed in the remote domain.</param>
        /// <param name="methodParameters">Method parameters. May not be changed in remote domain. Passed by value.
        /// All parameters must be marked with <see cref="System.SerializableAttribute"/> atribute.</param>
        /// <returns>Method's return value. Must be marked with <see cref="System.SerializableAttribute"/> atribute.</returns>
        object InvokeGenericMethod(object obj, string methodName, params object[] methodParameters);

        /// <summary>Marshals method arguments to process defined by the remoter, executes the generic method and returns the method's return value to source domain.</summary>
        /// <param name="type">Type which contains the specified static method.</param>
        /// <param name="methodName">Method to be executed.</param>
        /// <param name="methodParameters">Method parameters. May not be changed in remote domain. Passed by value.
        /// All parameters must be marked with <see cref="System.SerializableAttribute"/> atribute.</param>
        /// <returns>Method's return value. Must be marked with <see cref="System.SerializableAttribute"/> atribute.</returns>
        object InvokeGenericStaticMethod(Type type, string methodName, params object[] methodParameters);

        #endregion

        #region Properties.

        /// <summary>
        /// Gets or sets URL to which method calls are remoted.
        /// </summary>
        string Url { get; set; }

        /// <summary>
        /// Indicates whether method calls are actually remoted to another domain or whether methods are invoked directly on the given object. 
        /// </summary>
        bool ImplementsRemoting { get; }

        #endregion
    }
}